package io.leo.leoui.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import io.leo.leoui.listener.OnProgressChangedListener;
import io.leo.leoutils.DisplayUtils;


public class RoundProgressbar extends View {
    private Context context;

    private int bgColor=0xffe0b439;
    private int progressColor=0xff46a489;
    private int buttonColor=0xff46a489;
    private Paint bgPaint;
    private Paint progressPaint;
    private Paint buttonPaint;
    private int circleWidth;
    //按钮的溢出大小
    private int buttonOverflow;



    private OnProgressChangedListener listener;

    private int currentProgress=0;
    private int maxProgress=100;
    private int progressStep=1;

    //最小半径
    private int minRadius;

    //是否能拖动，如果设置成能，可以当成进度条使用
    private boolean canSwipe=true;

    private float[] pointPos=new float[2];
    public RoundProgressbar(Context context) {
        this(context,null);
    }

    public RoundProgressbar(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public RoundProgressbar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init(context);
    }


    void init(Context context) {
        circleWidth = DisplayUtils.dp2Px(context,14);
        buttonOverflow = DisplayUtils.dp2Px(context,5);
        bgPaint = new Paint();
        bgPaint.setColor(bgColor);
        bgPaint.setStyle(Paint.Style.STROKE);
        bgPaint.setStrokeWidth(circleWidth);
        bgPaint.setAntiAlias(true);

        progressPaint = new Paint();
        progressPaint.setColor(progressColor);
        progressPaint.setStyle(Paint.Style.STROKE);
        progressPaint.setStrokeWidth(circleWidth);
        progressPaint.setAntiAlias(true);
        progressPaint.setStrokeCap(Paint.Cap.ROUND);


        buttonPaint = new Paint();
        buttonPaint.setColor(buttonColor);
        buttonPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        buttonPaint.setAntiAlias(true);

    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        minRadius=Math.max(getMeasuredHeight(),getMeasuredWidth());
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int viewWidth=getWidth();
        int viewHeight=getHeight();


        RectF oval = new RectF(0+circleWidth/2+buttonOverflow,0+circleWidth/2+buttonOverflow,
                viewHeight - circleWidth/2-buttonOverflow, viewHeight - circleWidth/2-buttonOverflow);

        float angle = progressToAngle(currentProgress);
        Log.i("angle", String.valueOf(angle));
        canvas.drawArc(oval,-90,360,false,bgPaint);
        canvas.drawArc(oval,-90,angle,false,progressPaint);
        getPosByAngle(angle,oval);
        canvas.drawCircle(pointPos[0],pointPos[1],radius(),buttonPaint);
        Log.i("xy", String.valueOf(pointPos[0])+","+String.valueOf(pointPos[1]));

    }

    public void getPosByAngle(float angle,RectF oval){
        if (angle>=360.0) angle=359.0f;
        else if (angle<=0.0f) angle=0.1f;
        Log.i("getPosByAngle","angle is "+angle);
        Path path = new Path();
        path.addArc(oval,-90,angle);
        PathMeasure measure = new PathMeasure(path,false);
        measure.getPosTan(measure.getLength()*1, pointPos, null);
    }

    public void setCanSwipe(boolean canSwipe) {
        this.canSwipe = canSwipe;
    }

    public void setProgress(int progress){
        if (progress>maxProgress || progress<0)
            throw new IndexOutOfBoundsException("MaxProgress is "+maxProgress+",input is "+progress);
        this.currentProgress = progress;
        if (listener!=null)
            listener.onChanged(progress);
        invalidate();
    }

    public int getProgress(){
        return currentProgress;
    }
    public void setMax(int max){
        maxProgress = max;
    }


    public void setOnProgressChangedListener(OnProgressChangedListener listener){
        this.listener = listener;
    }

    private int progressToAngle(int progress){
       return  (int) ((float)progress/(float)(maxProgress+1)*360);
    }

    private int angleToProgress(int angle){
        return (int) ((float)angle/360.0f*(maxProgress+1));
    }



    private boolean isTouching=false;
    private float lastTouchX,lastTouchY;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!canSwipe)return false;
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:

                RectF pointIndex = new RectF(pointPos[0]-radius(),pointPos[1]-radius(),pointPos[0]+radius(),pointPos[1]+radius());
                Log.i("TOUCHXY",event.getX()+","+event.getY());
                if (pointIndex.contains(event.getX(),event.getY())) {
                    isTouching = true;
                    Log.i("TOUCHING","DOWN...");
                }else return false;
                lastTouchX=event.getX();lastTouchY=event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (isTouching){
                    Log.i("lastTouch And getRawX",lastTouchX+"，"+event.getRawX());
                    int angle = getRotationBetweenLines(getWidth()/2, getHeight()/2,event.getX(),event.getY());
                    int currProgress = angleToProgress(angle);
                    if (currProgress-getProgress()>5&&getProgress()==0)
                        return true;
                    if (currProgress!=maxProgress-1&&getProgress()==maxProgress)
                        return true;
                    if ((lastTouchX<=event.getX()||lastTouchY>=event.getY())&&getProgress()==maxProgress)
                        return true;
                    if ((lastTouchX>=event.getX()||lastTouchY>=event.getY())&&getProgress()==0)
                        return true;
                    setProgress(angleToProgress(angle));
                    lastTouchX=event.getX();lastTouchY=event.getY();
                }
                break;
            case MotionEvent.ACTION_UP:
                isTouching=false;
                break;
        }
        return true;
    }

    private float radius(){
        return circleWidth/2+buttonOverflow;
    }

    private int getRotationBetweenLines(float centerX, float centerY, float xInView, float yInView) {
        double rotation = 0;

        double k1 = (double) (centerY - centerY) / (centerX * 2 - centerX);
        double k2 = (double) (yInView - centerY) / (xInView - centerX);
        double tmpDegree = Math.atan((Math.abs(k1 - k2)) / (1 + k1 * k2)) / Math.PI * 180;

        if (xInView > centerX && yInView < centerY) {  //第一象限
            rotation = 90 - tmpDegree;
        } else if (xInView > centerX && yInView > centerY) //第二象限
        {
            rotation = 90 + tmpDegree;
        } else if (xInView < centerX && yInView > centerY) { //第三象限
            rotation = 270 - tmpDegree;
        } else if (xInView < centerX && yInView < centerY) { //第四象限
            rotation = 270 + tmpDegree;
        } else if (xInView == centerX && yInView < centerY) {
            rotation = 0;
        } else if (xInView == centerX && yInView > centerY) {
            rotation = 180;
        }

        return (int) rotation;
    }

}
